package com.my.magicApi.module;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.mongodb.client.result.UpdateResult;
import com.my.magicApi.utils.EncodeUtil;
import com.my.magicApi.utils.ExcelUtil;
import com.my.magicApi.utils.UploadFile;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.bson.Document;
import org.bson.types.Binary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.ssssssss.magicapi.core.annotation.MagicModule;
import org.ssssssss.magicapi.modules.servlet.RequestModule;
import org.ssssssss.magicapi.modules.servlet.ResponseModule;
import org.ssssssss.script.annotation.Comment;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

/**
 * @Author: Rip
 */
@Component
@MagicModule("mongoTemplete")
public class CustomMongoModule {

    private static final Logger logger = LoggerFactory.getLogger(CustomMongoModule.class);

    @Value("${file.host}")
    private String host;

    @Value("${server.port}")
    private String port;

    @Autowired
    MongoTemplate mongoTemplate;

    @Comment("aggregate")
    public AggregationResults<Object> aggregate(@Comment("aggregation") Aggregation aggregation, @Comment("collectName")String tableName) {
        logger.info("查询条件：{}", aggregation);
        return mongoTemplate.aggregate(aggregation, tableName, Object.class);
    }

    @Comment("find")
    public List<Object> find(@Comment("query")Query query, @Comment("collectName")String tableName) {
        logger.info("查询条件：{}", query);
        return mongoTemplate.find(query, Object.class, tableName);
    }

    @Comment("count")
    public Long count(@Comment("query")Query query,@Comment("class")Class<?> entityClass,@Comment("collectName")String tableName) {
        logger.info("查询条件：{}", query);
        return mongoTemplate.count(query, entityClass, tableName);
    }

    @Comment("update")
    public UpdateResult update(@Comment("query")Query query,@Comment("update") Update update, @Comment("collectName")String tableName) {
        logger.info("更新条件：{}", query);
        return mongoTemplate.updateFirst(query,update,tableName);
    }

    @Comment("save")
    public Object save(@Comment("entity")Object object,@Comment("collectionName")String collectionName) {
        logger.info("保存：{}", object);
        JSONObject entity = (JSONObject)JSONObject.toJSON(object);
        return mongoTemplate.insert(entity,collectionName);
    }


    @Comment("executeCommand")
    public Document executeCommand(@Comment("command") String command) {
        logger.info("执行语句：{}", command);
        return mongoTemplate.executeCommand(command);
    }

    @Comment("remove")
    public Object remove(@Comment("query") Query query,@Comment("collectionName") String collectionName) {
        logger.info("删除条件：{}", query);
        return mongoTemplate.remove(query,collectionName);
    }

    @Comment("exportExcel")
    public void exportExcel(RequestModule request, ResponseModule response, List list, String sheetName, List title,List field) throws Exception{
        String sheetStr = sheetName.substring(0, sheetName.lastIndexOf("."));
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet(sheetStr);
        //title样式
        HSSFCellStyle titleStyle = wb.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

//        String[] title = {"报备人员","性别","年龄","联系方式","身份证号码","抗原检测结果","现住址(街道+具体地址)","报备时间"};
        JSONArray titles = JSON.parseArray(JSONObject.toJSONString(title));
        JSONArray fields = JSON.parseArray(JSONObject.toJSONString(field));
        ExcelUtil.createExcelTitle(sheet, titles,titleStyle);
        if (CollectionUtils.isNotEmpty(list)){
            HSSFCellStyle valueStyle = wb.createCellStyle();
            valueStyle.setAlignment(HorizontalAlignment.CENTER);
            valueStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            //超长自动换行
            valueStyle.setWrapText(true);
            ExcelUtil.setExcelRowValue(sheet,list,valueStyle,fields);
        }
        response.setHeader("content-type","application/vnd.ms-excel");
        response.setHeader("character-encoding","ISO-8859-1");
        String fileName = EncodeUtil.encodeFileName(sheetName, request);
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Content-Disposition","attachment;filename="+fileName);
        wb.write(response.getOutputStream());
    }

    @Comment("export")
    public void export(RequestModule request, ResponseModule response,List list) throws Exception{
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("病毒抗原检测");
        //title样式
        HSSFCellStyle titleStyle = wb.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        String[] title = {"报备人员","性别","年龄","联系方式","身份证号码","抗原检测结果","现住址(街道+具体地址)","报备时间"};
        ExcelUtil.createTitle(sheet,title,titleStyle);
        if (CollectionUtils.isNotEmpty(list)){
            HSSFCellStyle valueStyle = wb.createCellStyle();
            valueStyle.setAlignment(HorizontalAlignment.CENTER);
            valueStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            //超长自动换行
            valueStyle.setWrapText(true);
            ExcelUtil.setRowValue(sheet,list,valueStyle);
        }
        response.setHeader("content-type","application/vnd.ms-excel");
        response.setHeader("character-encoding","ISO-8859-1");
        String fileName = EncodeUtil.encodeFileName("病毒抗原检测.xlsx", request);
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Content-Disposition","attachment;filename="+fileName);
        wb.write(response.getOutputStream());
    }


    @Comment("upload")
    public String upload(@RequestParam("file")@Comment("file") MultipartFile file) throws Exception{
        String fileName = file.getOriginalFilename();
        try {
            UploadFile uploadFile = new UploadFile();
            uploadFile.setName(fileName);
            uploadFile.setCreatedTime(new Date());
            uploadFile.setContent(new Binary(file.getBytes()));
            uploadFile.setContentType(file.getContentType());
            uploadFile.setSize(file.getSize());

            UploadFile savedFile = mongoTemplate.save(uploadFile);
            return savedFile.getId();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    @GetMapping(value = "/file/image/{id}", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
    @ResponseBody
    @Comment("downloadInfo")
    public byte[] image(@PathVariable String id){
        byte[] data = null;

        UploadFile file = mongoTemplate.findById(id, UploadFile.class);
        if(file != null){
            data = file.getContent().getData();
        }
        return data;
    }

    @GetMapping(value = "/file/{pictureGuid}", produces = {"application/octet-stream"})
    @ResponseBody
    public void download(RequestModule request, ResponseModule response, @PathVariable String pictureGuid) throws IOException{
        OutputStream outputStream = null;
        try{
            /** mongoDB 获取图片信息 **/

            UploadFile file = mongoTemplate.findById(pictureGuid,UploadFile.class);
            byte[] data = file.getContent().getData();
            outputStream = response.getOutputStream();
            response.setHeader("Content-Typ3e",file.getContentType());
            outputStream.write(data);
            outputStream.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            outputStream.close();
        }
    }

}
